use serde::Deserialize;
use serde::Serialize;
use ts_rs::TS;
use yata::core::PeriodType;
use yata::core::ValueType;

use super::IndicatorActionWrap;

///
/// Struct to hold the results of Struct Struct yata::indicators::CoppockCurve Coppock curve
///
///  参见[CPC](https://en.wikipedia.org/wiki/Coppock_curve)
///
#[derive(Serialize, Deserialize, Default, Debug, TS, Clone)]
#[ts(export)]
pub struct CPC {
    /// 3 signals
    /// Signal 1 appears when main value crosses zero line.
    /// When main value crosses zero line upwards, returns full buy signal.
    /// When main value crosses zero line downwards, returns full sell signal.
    pub signal0: Option<IndicatorActionWrap>,
    /// Signal 2 appears on reverse points of main value. When top reverse point appears,
    pub signal1: Option<IndicatorActionWrap>,
    /// Signal 3 appears on main value crosses signal line.
    /// When main value crosses signal line upwards, returns full buy signal.
    /// When main value crosses signal line downwards, returns full sell signal.
    pub signal2: Option<IndicatorActionWrap>,

    ///2 values
    ///Main value
    ///Range of values is the same as the range of the source values.
    ///
    pub main: ValueType,
    ///Signal line value
    ///Range of values is the same as the range of the source values.
    pub signal: ValueType,
}

/// Configuration Commodity Channel Index
#[derive(Serialize, Deserialize, Debug, TS, Clone, Copy)]
#[ts(export)]
pub struct CPCConfig {
    ///ma1: M
    ///Main MA type.
    ///
    ///Default is WMA(10)
    ///
    ///Period range in [2; PeriodType::MAX).
    pub ma1: PeriodType,

    ///s3_ma: M
    ///Signal line MA type .
    ///
    ///Default is EMA(5)
    ///
    ///Period range in [2; PeriodType::MAX).
    pub s3_ma: PeriodType,

    ///period2: PeriodType
    ///Long rate of change period. Default is 14.
    ///
    ///Range in (period3; PeriodType::MAX).
    pub period2: PeriodType,

    /// period3: PeriodType
    /// Short rate of change period. Default is 11.
    ///
    /// Range in [1; period2).
    pub period3: PeriodType,

    /// s2_left: PeriodType
    /// Signal 2 reverse points left limit. Default is 4.
    ///
    /// Range in [1; PeriodType::MAX-s2_right).
    pub s2_left: PeriodType,
    ///  s2_right: PeriodType
    ///  Signal 2 reverse points right limit. Default is 2
    ///  
    ///  Range in [1; PeriodType::MAX-s2_left).
    pub s2_right: PeriodType,
    // source: Source
    // Source type. Default is Close.
}

impl Default for CPCConfig {
    fn default() -> Self {
        Self {
            ma1: 10,
            s3_ma: 5,
            period2: 14,
            period3: 11,
            s2_left: 4,
            s2_right: 2,
        }
    }
}
